package com.quan.common.aspect;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.quan.common.annotation.RequiresPermissions;
import com.quan.common.utils.ExcludeUtils;
import com.quan.common.utils.IpHelper;
import com.quan.sso.common.pojo.SSOUser;
import com.quan.sso.common.tools.UserHolder;

@Component
@Aspect
public class AccessLogAspect {

	private static final Logger LOGGER = LoggerFactory.getLogger(AccessLogAspect.class);

	// 开始时间
	private long startTime = 0L;

	// 结束时间
	private long endTime = 0L;

	@Before("execution(* *..controller..*.*(..))")
	public void doBeforeInServiceLayer(JoinPoint joinPoint) {
		startTime = System.currentTimeMillis();
	}

	@After("execution(* *..controller..*.*(..))")
	public void doAfterInServiceLayer(JoinPoint joinPoint) {
	}

	@Around("execution(* *..controller..*.*(..))")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		// 获取request
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
		HttpServletRequest request = servletRequestAttributes.getRequest();

		// 从注解中获取操作名称、获取响应结果
		Object result = pjp.proceed();

		//判断当前域名是否不参与拦截
		if (!ExcludeUtils.excludeDomain(request)) {

			//判断当前请求是否不参与拦截
			if (!ExcludeUtils.excludeRequest(request)) {
				// 当前登录用户信息
				SSOUser user = UserHolder.getUser();

				Signature signature = pjp.getSignature();
				MethodSignature methodSignature = (MethodSignature) signature;
				Method method = methodSignature.getMethod();

				// 权限注解
				RequiresPermissions annotation = method.getAnnotation(RequiresPermissions.class);

				endTime = System.currentTimeMillis();
				LOGGER.info("用户:{}, 操作:{}, IP:{}, URI:{}, 耗时:{}(ms), UserAgent:{}", user != null ? user.getAccount() : "未登录", (annotation != null && !annotation.description().equals("") ? annotation.description() : "未注释"), IpHelper.getIpAddr(request), request.getRequestURL(), endTime - startTime, request.getHeader("User-Agent"));
			}
		}

		return result;
	}
}
